﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using BasePlatformNet;
using BasePlatformCommon;
using BasePlatformCommon.devChain;

namespace L9SubSet
{
	public partial class Form_SubDetail : Form
	{
		private int loopNum = 0;					// 巡检周期

		private bool refreshEnable = true;			// 刷新使能

		private bool showSubInfo = true;

		private bool showEquInfo = true;

		// 委托定义与声明
		public delegate void UpdateSubDetailInfoDelegate(List<ControlNode> controlNodeList);
		public UpdateSubDetailInfoDelegate updateSubDetailInfoDelegate;

		private string section = "SubDetail";		// 多语言文件配置节名称

		private string tip = "提示";					// MessageBox 题头

		/****************************************************************************/

		// 构造函数
		public Form_SubDetail()
		{
			InitializeComponent();

			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
			this.Font = new System.Drawing.Font(this.Font.Name, 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, ((byte)(134)));

			initEnvironment();
		}

		// 初始化运行环境
		private void initEnvironment()
		{
			updateSubDetailInfoDelegate = new UpdateSubDetailInfoDelegate(updateSubDetailInfo);

			// 设置本地化语言
			if (LanguageOper.available == true)
			{
				setLanguageText();
			}
		}

		// 设置本地化语言
		public void setLanguageText()
		{
			if (LanguageOper.available == false)
			{
				return;
			}

			LanguageOper.SetCurrentCulture();

			tip = LanguageOper.ReadValue("Common", "tipStr");

			// 界面控件文字
			this.Text = LanguageOper.ReadValue(section, "subDetail.Text");
			showSubCheckBox.Text = LanguageOper.ReadValue(section, "showSubCheckBox.Text");
			showEquCheckBox.Text = LanguageOper.ReadValue(section, "showEquCheckBox.Text");
			stopFreshButton.Text = LanguageOper.ReadValue(section, "stopFreshButton.Text.1");
			closeButton.Text = LanguageOper.ReadValue(section, "closeButton.Text");

			// 表格列头
			detailDataGridView.Columns[0].HeaderText = LanguageOper.ReadValue(section, "colHead.Text.0");
			detailDataGridView.Columns[1].HeaderText = LanguageOper.ReadValue(section, "colHead.Text.13");
			detailDataGridView.Columns[2].HeaderText = LanguageOper.ReadValue(section, "colHead.Text.1");
			detailDataGridView.Columns[3].HeaderText = LanguageOper.ReadValue(section, "colHead.Text.2");
			detailDataGridView.Columns[4].HeaderText = LanguageOper.ReadValue(section, "colHead.Text.3");
			detailDataGridView.Columns[5].HeaderText = LanguageOper.ReadValue(section, "colHead.Text.4");
			detailDataGridView.Columns[6].HeaderText = LanguageOper.ReadValue(section, "colHead.Text.5");
			detailDataGridView.Columns[7].HeaderText = LanguageOper.ReadValue(section, "colHead.Text.6");
			detailDataGridView.Columns[8].HeaderText = LanguageOper.ReadValue(section, "colHead.Text.7");
			detailDataGridView.Columns[9].HeaderText = LanguageOper.ReadValue(section, "colHead.Text.8");
			detailDataGridView.Columns[10].HeaderText = LanguageOper.ReadValue(section, "colHead.Text.9");
			detailDataGridView.Columns[11].HeaderText = LanguageOper.ReadValue(section, "colHead.Text.10");
			detailDataGridView.Columns[12].HeaderText = LanguageOper.ReadValue(section, "colHead.Text.11");
			detailDataGridView.Columns[13].HeaderText = LanguageOper.ReadValue(section, "colHead.Text.12");
		}

		// 更新分控详细信息
		private void updateSubDetailInfo(List<ControlNode> controlNodeList)
		{
			if (refreshEnable == false)
			{
				return;
			}

			loopNum++;
			if (loopNum > 1000000)
			{
				loopNum = 1;
			}

			int devNum = 0;
			if (controlNodeList != null)
			{
				List<ControlNode> localControlNodeList = new List<ControlNode>();

				// 更换顺序：附属设备在前, 分控在后
				foreach (ControlNode node in controlNodeList)
				{
					if (node.type == 0)
					{
						localControlNodeList.Add(node);
					}
				}
				foreach (ControlNode node in controlNodeList)
				{
					if (node.type == 1)
					{
						localControlNodeList.Add(node);
					}
				}

				// 更新用户界面信息
				for (int i = 0; i < localControlNodeList.Count; i++)
				{
					devNum++;
					DevInfo devInfo = new DevInfo(localControlNodeList[i]);
					if (devNum > detailDataGridView.Rows.Count)
					{
						addOneRow(devInfo);				// 添加行
					}
					else
					{
						updateOneRow(devNum, devInfo);	// 更新行
					}
				}
			}
			
			if (devNum < detailDataGridView.Rows.Count)
			{
				for (int rowIndex = detailDataGridView.Rows.Count - 1; rowIndex >= devNum; rowIndex--)
				{
					deleteOneRow(rowIndex);				// 删除行
				}
			}
		}

		// 添加行
		private void addOneRow(DevInfo devInfo)
		{
			string devIndexStr = String.Format(" {0}", devInfo.DevIndex);
			
			// 判断是否有等位节点
			if (devInfo.BrotherCount > 0)
			{
				devIndexStr += String.Format(" [{0}]", devInfo.BrotherCount + 1);
			}

			// 判断是否连续
			if (devInfo.NoContinueFlag == true)
			{
				devIndexStr += " *";
			}
			
			devIndexStr += " ";

			detailDataGridView.Rows.Add(devInfo.Selected, devInfo.DevTypeDetail, devIndexStr, devInfo.Fix, devInfo.SO, loopNum, devInfo.TotalComm, devInfo.ErrorComm, devInfo.CommStateStr,
				devInfo.PortA, devInfo.PortB, devInfo.InputPort, devInfo.LoopRing, devInfo.Version, "");

			int lastRowIndex = detailDataGridView.Rows.Count - 1;

			// 确定是否显示该行
			if (devInfo.DevType.Equals("Sub") && showSubInfo == false)
			{
				detailDataGridView.Rows[lastRowIndex].Visible = false;
			}
			else if (devInfo.DevType.Equals("Equ") && showEquInfo == false)
			{
				detailDataGridView.Rows[lastRowIndex].Visible = false;
			}
			else
			{
				detailDataGridView.Rows[lastRowIndex].Visible = true;
			}

			// 根据是否有等位节点改变行背景色
			if (devInfo.BrotherCount > 0)
			{
				detailDataGridView.Rows[lastRowIndex].DefaultCellStyle.ForeColor = Color.Red;
			}
			else
			{
				detailDataGridView.Rows[lastRowIndex].DefaultCellStyle.ForeColor = Color.Black;
			}
		}

		// 更新行
		private void updateOneRow(int rowIndex, DevInfo devInfo)
		{
			rowIndex--;

			string devIndexStr = String.Format(" {0}", devInfo.DevIndex);

			// 判断是否有等位节点
			if (devInfo.BrotherCount > 0)
			{
				devIndexStr += String.Format(" [{0}]", devInfo.BrotherCount + 1);
				detailDataGridView.Rows[rowIndex].DefaultCellStyle.ForeColor = Color.Red;
			}
			else
			{
				detailDataGridView.Rows[rowIndex].DefaultCellStyle.ForeColor = Color.Black;
			}

			// 判断是否连续
			if (devInfo.NoContinueFlag == true)
			{
				devIndexStr += " *";
			}

			devIndexStr += " ";

			detailDataGridView.Rows[rowIndex].Cells["SubIndex"].Value = devIndexStr;
			detailDataGridView.Rows[rowIndex].Cells["DevType"].Value = devInfo.DevType;
			detailDataGridView.Rows[rowIndex].Cells["Selected"].Value = devInfo.Selected;
			detailDataGridView.Rows[rowIndex].Cells["Fix"].Value = devInfo.Fix;
			detailDataGridView.Rows[rowIndex].Cells["SO"].Value = devInfo.SO;
			detailDataGridView.Rows[rowIndex].Cells["LoopNumStr"].Value = loopNum;
			detailDataGridView.Rows[rowIndex].Cells["TotalComm"].Value = devInfo.TotalComm;
			detailDataGridView.Rows[rowIndex].Cells["ErrorComm"].Value = devInfo.ErrorComm;
			detailDataGridView.Rows[rowIndex].Cells["CommStateStr"].Value = devInfo.CommStateStr;
			detailDataGridView.Rows[rowIndex].Cells["PortA"].Value = devInfo.PortA;
			detailDataGridView.Rows[rowIndex].Cells["PortB"].Value = devInfo.PortB;
			detailDataGridView.Rows[rowIndex].Cells["InputPort"].Value = devInfo.InputPort;
			detailDataGridView.Rows[rowIndex].Cells["LoopRing"].Value = devInfo.LoopRing;
			detailDataGridView.Rows[rowIndex].Cells["Version"].Value = devInfo.Version;
			detailDataGridView.Rows[rowIndex].Cells["ErrorLampNum"].Value = devInfo.ErrorLampNum;

			// 确定是否显示该行
			if (devInfo.DevType.Equals("Sub") && showSubInfo == false)
			{
				detailDataGridView.Rows[rowIndex].Visible = false;
			}
			else if (devInfo.DevType.Equals("Equ") && showEquInfo == false)
			{
				detailDataGridView.Rows[rowIndex].Visible = false;
			}
			else
			{
				detailDataGridView.Rows[rowIndex].Visible = true;
			}
		}

		// 删除行
		private void deleteOneRow(int rowIndex)
		{
			detailDataGridView.Rows.RemoveAt(rowIndex);
		}

		// 关闭
		private void closeButton_Click(object sender, EventArgs e)
		{
			this.Close();
		}

		// 重加载时，重置检测周期
		private void Form_SubDetail_Load(object sender, EventArgs e)
		{
			loopNum = 0;
		}

		// 开始刷新/停止刷新
		private void stopFreshButton_Click(object sender, EventArgs e)
		{
			// 停止刷新
			if (refreshEnable == true)
			{
				string text = "开始刷新";
				if (LanguageOper.available == true)
				{
					text = LanguageOper.ReadValue(section, "stopFreshButton.Text.0");
				}
				stopFreshButton.Text = text;
				refreshEnable = false;
			}
			else
			{
				string text = "停止刷新";
				if (LanguageOper.available == true)
				{
					text = LanguageOper.ReadValue(section, "stopFreshButton.Text.1");
				}
				stopFreshButton.Text = text;
				refreshEnable = true;
			}
		}

		// 显示分控
		private void showSubCheckBox_CheckedChanged(object sender, EventArgs e)
		{
			showSubInfo = showSubCheckBox.Checked;
			if (refreshEnable == false)
			{
				manualUpdateRowVisible();
			}
		}

		// 显示附属设备
		private void showEquCheckBox_CheckedChanged(object sender, EventArgs e)
		{
			showEquInfo = showEquCheckBox.Checked;
			if (refreshEnable == false)
			{
				manualUpdateRowVisible();
			}
		}

		// 手动筛选显示的行, 专用于停止刷新时的操作
		private void manualUpdateRowVisible()
		{
			for (int i = 0; i < detailDataGridView.Rows.Count; i++)
			{
				// 确定是否显示该行
				if (detailDataGridView.Rows[i].Cells["DevType"].Value.ToString().Equals("Sub") && showSubInfo == false)
				{
					detailDataGridView.Rows[i].Visible = false;
				}
				else if (detailDataGridView.Rows[i].Cells["DevType"].Value.ToString().Equals("Equ") && showEquInfo == false)
				{
					detailDataGridView.Rows[i].Visible = false;
				}
				else
				{
					detailDataGridView.Rows[i].Visible = true;
				}
			}
		}
	}

	#region 内部使用的类和枚举

	public class DevInfo
	{
		public int DevIndex { get; set; }				// 级联深度

		public string DevType { get; set; }				// 设备类型：Sub/Equ

		public bool Selected { get; set; }				// 选中标记

		public string Fix { get; set; }					// 固化

		public string SO { get; set; }					// 串出

		public int TotalComm { get; set; }				// 总包数

		public int ErrorComm { get; set; }				// 错误包数

		public string CommStateStr { get; set; }		// 状态

		public string PortA { get; set; }				// A口

		public string PortB { get; set; }				// B口

		public string InputPort { get; set; }			// 入口

		public string Version { get; set; }				// 版本

        public string LoopRing { get; set; }			// 环路

        public string DevTypeDetail { get; set; }		// 设备详细类型

		/***********************************************************/

		public int BrotherCount { get; set; }			// 等位设备节点数量

		public bool NoContinueFlag { get; set; }		// 设备序号不连续标记

		public List<SubPort> SubPortList { get; set; }	// 端口数据集合

		public int TotalSubPortNum { get; set; }		// 端口数

		public int TotalLampNum { get; set; }			// 总灯点数

		public int ErrorLampNum { get; set; }			// 异常灯点数

		public bool ReachMaxPacketNum {	get; set; }		// 总包数或错包数达到最大

		private byte[] replyDataBytes = new byte[256];

		private string section = "SubInfo";				// 多语言文件配置节名称

		// 构造函数
		public DevInfo(ControlNode controlNode)
		{
			if (controlNode.type == 0)
			{
                DevType = "Equ";
                DevTypeDetail = "Equ";
				DevIndex = controlNode.myEquipmentDepth + 1;
				Selected = false;
				Version = controlNode.version;
				BrotherCount = controlNode.brotherCount;
				NoContinueFlag = controlNode.noContinueFlag;
				SubPortList = new List<SubPort>();
				Array.Copy(controlNode.replyData, replyDataBytes, 256);
				parseReplyDataBytes();
			}
			else
			{
                DevType = "Sub";
                DevTypeDetail = ControlNode.getSubTypeString(controlNode.subType);
				DevIndex = controlNode.mySubCtrlDepth + 1;
				Selected = false;
				Version = controlNode.version;
				BrotherCount = controlNode.brotherCount;
				NoContinueFlag = controlNode.noContinueFlag;
				SubPortList = new List<SubPort>();
				Array.Copy(controlNode.replyData, replyDataBytes, 256);
				parseReplyDataBytes();
			}
		}
		
		// 解析分控状态反馈数据 - 256 byte
		private void parseReplyDataBytes()
		{
			string noConnectText = "未连接";
			string loopStr1 = "无";
			string loopStr2 = "环路";
			string commStr1 = "正常";
			string commStr2 = "不良";
			string commStr3 = "异常";
			if (LanguageOper.available == true)
			{
				noConnectText = LanguageOper.ReadValue(section, "str.0");
				loopStr1 = LanguageOper.ReadValue(section, "str.1");
				loopStr1 = LanguageOper.ReadValue(section, "str.2");
				commStr1 = LanguageOper.ReadValue(section, "str.3");
				commStr2 = LanguageOper.ReadValue(section, "str.4");
				commStr3 = LanguageOper.ReadValue(section, "str.5");
			}

			// 字节 0x30 - bit0 - 固化
			if ((replyDataBytes[0x30] >> 0 & 0x1) == 0x0)
			{
				Fix = "OFF";
			}
			else if ((replyDataBytes[0x30] >> 0 & 0x1) == 0x1)
			{
				Fix = "ON";
			}

			// 字节 0x30 - bit1 - 串出
			if ((replyDataBytes[0x30] >> 1 & 0x1) == 0x0)
			{
				SO = "OFF";
			}
			else if ((replyDataBytes[0x30] >> 1 & 0x1) == 0x1)
			{
				SO = "ON";
			}

			// 字节 0x06 - bit[1:0] - A口速率
			if ((replyDataBytes[0x06] >> 0 & 0x3) == 0x0)
			{
				PortA = noConnectText;
			}
			else if ((replyDataBytes[0x06] >> 0 & 0x3) == 0x1)
			{
				PortA = "1G";
			}
			else if ((replyDataBytes[0x06] >> 0 & 0x3) == 0x2)
			{
				PortA = "100M";
			}
			else if ((replyDataBytes[0x06] >> 0 & 0x3) == 0x3)
			{
				PortA = "10M";
			}

			// 字节 0x06 - bit[3:2] - B口速率
			if ((replyDataBytes[0x06] >> 2 & 0x3) == 0x0)
			{
				PortB = noConnectText;
			}
			else if ((replyDataBytes[0x06] >> 2 & 0x3) == 0x1)
			{
				PortB = "1G";
			}
			else if ((replyDataBytes[0x06] >> 2 & 0x3) == 0x2)
			{
				PortB = "100M";
			}
			else if ((replyDataBytes[0x06] >> 2 & 0x3) == 0x3)
			{
				PortB = "10M";
			}

			// 字节 0x06 - bit6 - 入口
			if ((replyDataBytes[0x06] >> 6 & 0x1) == 0x0)
			{
				InputPort = "A";
			}
			else if ((replyDataBytes[0x06] >> 6 & 0x1) == 0x1)
			{
				InputPort = "B";
			}

			// 字节 0x06 - bit7 - 环路
			if ((replyDataBytes[0x06] >> 7 & 0x1) == 0x0)
			{
				LoopRing = loopStr1;
			}
			else if ((replyDataBytes[0x06] >> 7 & 0x1) == 0x1)
			{
				LoopRing = loopStr2;
			}

			// 错误包数
			ErrorComm = replyDataBytes[0] | replyDataBytes[1] << 8;

			// 总包数
			TotalComm = replyDataBytes[2] | replyDataBytes[3] << 8 | replyDataBytes[4] << 16 | replyDataBytes[5] << 24;

            //if (replyDataBytes.Length>64) {
                // 添加端口 Port1-Port8, 并解析总点数与错误点数
                SubPort port1 = new SubPort();
                port1.index = 0;
                port1.TotalLampNum = replyDataBytes[0x80] | replyDataBytes[0x81] << 8;	// Port1 总点数
                port1.ErrorLampNum = replyDataBytes[0x82] | replyDataBytes[0x83] << 8;	// Port1 错误点数
                SubPort port2 = new SubPort();
                port2.index = 1;
                port2.TotalLampNum = replyDataBytes[0x84] | replyDataBytes[0x85] << 8;	// Port2 总点数
                port2.ErrorLampNum = replyDataBytes[0x86] | replyDataBytes[0x87] << 8;	// Port2 错误点数
                SubPort port3 = new SubPort();
                port3.index = 2;
                port3.TotalLampNum = replyDataBytes[0x88] | replyDataBytes[0x89] << 8;	// Port3 总点数
                port3.ErrorLampNum = replyDataBytes[0x8a] | replyDataBytes[0x8b] << 8;	// Port3 错误点数
                SubPort port4 = new SubPort();
                port4.index = 3;
                port4.TotalLampNum = replyDataBytes[0x8c] | replyDataBytes[0x8d] << 8;	// Port4 总点数
                port4.ErrorLampNum = replyDataBytes[0x8e] | replyDataBytes[0x8f] << 8;	// Port4 错误点数
                SubPort port5 = new SubPort();
                port5.index = 4;
                port5.TotalLampNum = replyDataBytes[0x90] | replyDataBytes[0x91] << 8;	// Port5 总点数
                port5.ErrorLampNum = replyDataBytes[0x92] | replyDataBytes[0x93] << 8;	// Port5 错误点数
                SubPort port6 = new SubPort();
                port6.index = 5;
                port6.TotalLampNum = replyDataBytes[0x94] | replyDataBytes[0x95] << 8;	// Port6 总点数
                port6.ErrorLampNum = replyDataBytes[0x96] | replyDataBytes[0x97] << 8;	// Port6 错误点数
                SubPort port7 = new SubPort();
                port7.index = 6;
                port7.TotalLampNum = replyDataBytes[0x98] | replyDataBytes[0x99] << 8;	// Port7 总点数
                port7.ErrorLampNum = replyDataBytes[0x9a] | replyDataBytes[0x9b] << 8;	// Port7 错误点数
                SubPort port8 = new SubPort();
                port8.index = 7;
                port8.TotalLampNum = replyDataBytes[0x9c] | replyDataBytes[0x9d] << 8;	// Port8 总点数
                port8.ErrorLampNum = replyDataBytes[0x9e] | replyDataBytes[0x9f] << 8;	// Port8 错误点数

                SubPortList.Clear();

                SubPortList.Add(port1);
                SubPortList.Add(port2);
                SubPortList.Add(port3);
                SubPortList.Add(port4);
                SubPortList.Add(port5);
                SubPortList.Add(port6);
                SubPortList.Add(port7);
                SubPortList.Add(port8);

                // 分控端口数
                TotalSubPortNum = SubPortList.Count;

                // 分控总灯点数
                TotalLampNum = port1.TotalLampNum + port2.TotalLampNum + port3.TotalLampNum + port4.TotalLampNum
                                + port5.TotalLampNum + port6.TotalLampNum + port7.TotalLampNum + port8.TotalLampNum;

                // 分控异常灯点数
                ErrorLampNum = port1.ErrorLampNum + port2.ErrorLampNum + port3.ErrorLampNum + port4.ErrorLampNum
                                + port5.ErrorLampNum + port6.ErrorLampNum + port7.ErrorLampNum + port8.ErrorLampNum;
            //}

			double factor = 0.0;
			if (TotalLampNum > 0)
			{
				factor = ((double)ErrorComm) / ((double)TotalComm);
			}

			if (factor <= 0.3)
			{
				CommStateStr = commStr1;	// 通信正常
			}
			else if (factor > 0.3 && factor < 0.7)
			{
				CommStateStr = commStr2;	// 通信不良
			}
			else
			{
				CommStateStr = commStr3;	// 通信异常
			}

			// 判断总包数、错包数是否达到最大
			if (TotalComm >= 2147483648 - 100 || ErrorComm >= 32768 - 100)
			{
				ReachMaxPacketNum = true;
			}
			else
			{
				ReachMaxPacketNum = false;
			}
		}
	}

	#endregion
}
